Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add focusin and focusout events #10235

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

josepharhar
Copy link
Contributor

@josepharhar josepharhar commented Mar 29, 2024

These events are already implemented in browsers and are documented on MDN. This PR also adds onfocusin and onfocusout event handler content attributes.

#3514 tracks this and other focus events.

Fixes #10234

(See WHATWG Working Mode: Changes for more details.)


/dom.html ( diff )
/indices.html ( diff )
/interaction.html ( diff )
/webappapis.html ( diff )

These events are already implemented in browsers and are documented on
MDN. This PR also adds onfocusin and onfocusout event handler content
attributes.

whatwg#3514 tracks this and other focus
events.

Fixes whatwg#10234
Copy link
Member

@domenic domenic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wow, great work tackling this very-old gap in the spec. It ended up not being so bad after all.

@@ -79902,12 +79920,12 @@ dictionary <dfn dictionary>ToggleEventInit</dfn> : <span>EventInit</span> {
</ol>

<p>To <dfn>fire a focus event</dfn> named <var>e</var> at an element <var>t</var> with a given
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's make this more of a normal algorithm declaration:

To fire a focus event named event at an element target given an element relatedTarget and an optional boolean bubbles (default false), ...

And then update call sites to uniformly be either

[fire a focus event] named foo at bar given baz

or

[fire a focus event] named foo at bar given baz and true

@@ -13135,6 +13135,8 @@ https://software.hixie.ch/utilities/js/live-dom-viewer/?%3C%21DOCTYPE%20HTML%3E%
<li><code data-x="handler-onended">onended</code></li>
<li><code data-x="handler-onerror">onerror</code>*</li>
<li><code data-x="handler-onfocus">onfocus</code>*</li>
<li><code data-x="handler-onfocusin">onfocusin</code>*</li>
<li><code data-x="handler-onfocusout">onfocusout</code>*</li>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This * means that they belong to the "Window-reflecting body element event handler set" instead of being the normal list at the top of https://whatpr.org/html/10235/webappapis.html#event-handlers-on-elements,-document-objects,-and-window-objects .

Can you confirm that difference is tested? (I'm honestly not sure exactly how you would test, this will take a bit of research. Or maybe change something in the implementation and see if any tests start failing.)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, I see that for example onclick is in the first table and onfocus is in the second one.
I made a quick test page, and it would seem that document.body doesn't do onfocus, but it does to onclick, and that was the only difference that I found.

Does that match up with your understanding?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the difference in your test is due to the difference between click being bubbling and focus not.

The example below https://html.spec.whatwg.org/#the-body-element:window-reflecting-body-element-event-handler-set seems to have a possible test case at least for bubbling events.

I bet in Chromium there's some list hidden somewhere for the special ones.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah I see, here it is: https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/renderer/core/html/html_body_element.cc;l=115-216;drc=c0c69be50d661fd4952865e0aaf76952d9272f17
These are just for when they're set as HTML attributes rather than element.onfocusin which I am trying to implement in chromium to match safari.
It looks like chromium already implements onfocusin as an HTML attribute, but it is not included in the special body->window logic that onfocus has: https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/renderer/core/html/html_element.cc;l=481-482;drc=040547c1a7d0987ca63e18ca010986113637bf51

So I guess that we should put onfocusin/onfocusout in the list that onfocus is not in? So I should remove that asterisk?

I also made a test page here, but the results only made me confused: https://jsfiddle.net/jarhar/84jLcptn/5/

Screenshot 2024-04-02 at 5 09 28 PM Screenshot 2024-04-02 at 5 11 08 PM

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So I guess that we should put onfocusin/onfocusout in the list that onfocus is not in? So I should remove that asterisk?

Yes, I think that makes the most sense.

For testing, I figured out what we can do.

If you look at https://github.com/web-platform-tests/wpt/blob/master/html/webappapis/scripting/events/resources/event-handler-body.js , it pulls a list of all event handlers from the html.idl file. It then uses the windowReflectingBodyElementEventHandlerSet declaration to test how they should behave.

So, if we decide these should be in the "normal" list, we do no work. Updating the spec will eventually cause html.idl in the WPT repo to update, which will automatically make those tests start testing the right thing.

For your implementation, to verify everything is working correctly, you can modify the html.idl file locally, and make sure the tests still pass. When I do that right now, Chromium does not yet pass, I'd guess because the content attribute reflection isn't implemented. If you can confirm your patch makes such a local change pass, then I'll feel confident about our test coverage.

@domenic
Copy link
Member

domenic commented Apr 1, 2024

Browsing Blink source code I found these interesting if statements:

https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/renderer/core/page/focus_controller.cc;l=434;drc=2a6270727b6a7bbcd17ab585dc81ea4fc5a44d71

https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/renderer/core/page/focus_controller.cc;l=445?q=DOMFocusIn&ss=chromium

https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/renderer/core/dom/document.cc;l=5601-5607;drc=ebef5d0e968e4b5519062305af9856f53c41eb2f

I think these can have interesting impacts if you call focus()/blur() inside of a focus/blur event handler. Doing so might prevent focusin / focusout from being fired.

Should we add that to the spec? Do we have tests for such cases?

@josepharhar
Copy link
Contributor Author

Should we add that to the spec?

Nice, definitely!

Do we have tests for such cases?

I removed the logic in a chromium patch and am running all tests on it now to find out

@josepharhar
Copy link
Contributor Author

I removed the logic in a chromium patch and am running all tests on it now to find out

https://chromium-review.googlesource.com/c/chromium/src/+/5411398

There are a bunch of tests that failed but most of them are non-WPT. There was one WPT that failed, but actually as a crash so I'm not sure if the test is actually testing this behavior: css/selectors/focus-visible-023.html.

It looks to me like we should keep this behavior in blink, add it to this spec, and add tests for it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

Successfully merging this pull request may close these issues.

onfocusout and onfocusin event handler content attributes
2 participants